package com.tom.architect02.p4.day38.simple6.base;

import android.os.Bundle;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.tom.architect02.p4.day38.simple6.inject.InjectPresenter;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * Added by Tom on 2024/01/29. <BaseView>
 */
public abstract class BaseMvpActivity<P extends BasePresenter>
        extends AppCompatActivity implements BaseView {
    private P mPresenter; // 主的Presenter。处理一对一的情况(一个View 仅对应一个Presenter)
    // 缓存起来Presenter
    private List<BasePresenter> mPresenters; // 一对多的 非主Presenter，缓存起来，统一detach。

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView();
        mPresenters = new ArrayList<>();

        // 创建P, 交给子类具体去时间。
        mPresenter = createPresenter();
        mPresenter.attach(this); // 绑定

        handleInjects();
        initView();
        initData();
    }

    // 处理 InjectPresenter 注入
    private void handleInjects() {
        // 2. 处理注入Presenter。有就注入，没有就不处理。通过反射(也可以通过Dagger来实现)
        // 解决一个View里面有多个Presenter的情况。
        Field[] fields = this.getClass().getDeclaredFields();
        for (Field field : fields) {
            InjectPresenter injectPresenter = field.getAnnotation(InjectPresenter.class);
            if (injectPresenter != null) {
                // 创建注入。
                Class<? extends BasePresenter> presentClazz = null;
                // 做类型的判断。可以获取继承的父类，如果不是继承BasePresenter，就抛异常处理。
                try {
                    presentClazz = (Class<? extends BasePresenter>) field.getType();
                } catch (Exception e) {
                    // 处理别的注入。
                    throw new RuntimeException("不支持的注入类型，请注入InjectPresenter：" + field.getType().getName());
                }
                try {
                    // 创建Presenter对象。
                    BasePresenter basePresenter = presentClazz.newInstance();
                    basePresenter.attach(this); // 如何解决解绑。
                    mPresenters.add(basePresenter); // 缓存起来。
                    // 设置Presenter对象
                    field.setAccessible(true);
                    field.set(this, basePresenter); // 给对象mPresenter1，mPresenter2 赋值。
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 子类去实现，每个Activity 实现不同。
    protected abstract P createPresenter();

    public P getPresenter() {
        return mPresenter;
    }

    protected abstract void initView();

    protected abstract void initData();

    protected abstract void setContentView();

    @Override
    public void onDestroy() {
        super.onDestroy();
        mPresenter.detach();
        for (BasePresenter presenter : mPresenters) {
            // 解绑。
            presenter.detach();
        }
    }

}
